﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using XNALibrary;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using XNALibrary.ZCAMERA;
using XNALibrary.OmniCamera;
using Microsoft.Xna.Framework.Content;
using XNALibrary.Interfaces;

namespace XNALibrary
{
    public delegate void CurrentRenderMethod(RenderControl rc, GameTime gt);
   
    public class RenderControl
    {
        public List<IRenderable> Renderables;
        public List<IPointLight> LightSources;
        public ICamera CurrentCamera;
        public SpriteBatch SpriteBatch { get { if (spriteBatch == null) spriteBatch = new SpriteBatch(graphicsDevice); return spriteBatch; } }
        public ContentManager ContentManager;

        public GraphicsDevice graphicsDevice;
        private SpriteBatch spriteBatch;
       
        public RenderControl(Game game)
        {
            this.graphicsDevice = game.GraphicsDevice;
            this.ContentManager = new ContentManager(game.Services);

            CurrentCamera = new FPCamera(graphicsDevice, new Vector3(0, 500, 0), Vector3.Down, Vector3.Left, Vector3.Zero);
            Renderables = new List<IRenderable>();
            LightSources = new List<IPointLight>();
        }

        public RenderControl(Game game, ICamera camera) : this(game)
        {
            CurrentCamera = camera;
        }

        public void Update(GameTime gt)
        {
            CurrentCamera.Update(gt);
        }

        public void Draw(GameTime gt)
        {
            foreach (IRenderable ir in Renderables)
                ir.Render(this, gt);
        }

        public IPointLight[] GetLights(Vector3 position, int numLights)
        {
            if (LightSources.Count < numLights)
                return LightSources.ToArray();
            else
            {
                PointLight[] rv = new PointLight[numLights];
                List<IPointLight> lights = new List<IPointLight>(LightSources.ToArray());
                lights.Sort(new DistanceComparer(position));
                Array.Copy(LightSources.ToArray(), rv, numLights);
                return rv;
            }
        }

        private class DistanceComparer : Comparer<IPointLight>
        {
            Vector3 targetPos;
            public DistanceComparer(Vector3 pos)
            {
                targetPos = pos;
            }

            public override int Compare(IPointLight x, IPointLight y)
            {
                float xDist, yDist;
                xDist = Vector3.DistanceSquared(x.Position, targetPos);
                yDist = Vector3.DistanceSquared(y.Position, targetPos);
                if (xDist > yDist)
                    return 1;
                else if (xDist < yDist)
                    return -1;
                else
                    return 0;
            }
        }



    }
}
